package com.scwatch.core.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.scwatch.common.file.FileHandler;
import com.scwatch.common.web.PathResolver;
import com.scwatch.core.constant.Constants;
import com.scwatch.core.domain.*;
import com.scwatch.core.html.HtmlGenerator;
import com.scwatch.core.html.HtmlService;
import com.scwatch.core.html.PInfo;
import com.scwatch.core.listener.*;
import com.scwatch.core.repository.InfoDao;
import com.scwatch.core.service.*;
import com.scwatch.core.support.DeleteException;
import com.scwatch.core.support.UploadHandler;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.*;

/**
 * 信息Service实现
 *
 * @author gjl
 */
@Service
@Transactional
public class InfoServiceImpl implements InfoService, SiteDeleteListener, OrgDeleteListener, NodeDeleteListener,
        UserDeleteListener {
    private static final Logger logger = LoggerFactory.getLogger(InfoServiceImpl.class);

    public Info save(Info bean, InfoDetail detail, Integer[] nodeIds, Integer[] specialIds, Integer[] viewGroupIds,
                     Integer[] viewOrgIds,Integer[]voteIds, Map<String, String> customs, Map<String, String> clobs, List<InfoImage> images,
                     List<InfoFile> files, Integer[] attrIds, Map<String, String> attrImages, String[] tagNames, Integer nodeId,
                     Integer creatorId, String status, Integer siteId) {
        bean.setSite(siteService.get(siteId));
        User creator = userService.get(creatorId);
        bean.setCreator(creator);
        bean.setOrg(creator.getOrg());
        Node node = nodeService.refer(nodeId);
        bean.setNode(node);
        if (customs != null) {
            bean.setCustoms(customs);
        }
        sanitizeClob(clobs);
        bean.setClobs(clobs);
        if (images != null) {
            bean.setImages(images);
        }
        if (files != null) {
            bean.setFiles(files);
        }
        try {
            extractImage(bean.getSite(), creatorId, node, detail, images, clobs, attrIds, attrImages);
        } catch (Exception e) {
            logger.error("extract image error!", e);
        }

        if (StringUtils.isNotBlank(detail.getSmallImage())) {
            bean.setWithImage(true);
        } else {
            bean.setWithImage(false);
        }
        Workflow workflow = null;
        if (Info.DRAFT.equals(status) || Info.CONTRIBUTION.equals(status) || Info.COLLECTED.equals(status)) {
            // 草稿、投稿、采集
            bean.setStatus(status);
        } else {
            workflow = node.getWorkflow();
            if (workflow != null) {
                bean.setStatus(Info.AUDITING);
            } else {
                if(bean.getStatus()==null){
                    bean.setStatus("1");
                }
            }
        }
        bean.applyDefaultValue();
//        bean.adjustStatus();
        if(bean.getNewsType()==null || (bean.getNewsType()!=null && bean.getNewsType().intValue()!=5 && bean.getNewsType().intValue()!=4 && bean.getNewsType().intValue()!=6)){
            if(bean.getDetail()==null ||bean.getDetail().getDisclosetype()==null){
                if(detail.getVideo()!=null){   //视频新闻
                    bean.setNewsType(3);
                }else if(detail.getFile()!=null){ //音频新闻
                    bean.setNewsType(2);
                }else{
                    bean.setNewsType(1);
                }
            }
        }
        if(StringUtils.isNotBlank(bean.getLink())){
            bean.setNewsType(6);
        }
        bean = dao.save(bean);
        infoDetailService.save(detail, bean);
        // 将InfoBuffer对象一并保存，以免在网页浏览时再保存，导致并发保存报错
        infoBufferService.save(new InfoBuffer(), bean);
        infoAttrService.update(bean, attrIds, attrImages);
        infoNodeService.update(bean, nodeIds, nodeId);
        infoTagService.update(bean, tagNames);
        infoSpecialService.update(bean, specialIds);
        infoVoteService.update(bean,voteIds);
        infoMemberGroupService.update(bean, viewGroupIds);
        infoOrgService.update(bean, viewOrgIds);
        attachmentRefService.update(bean.getAttachUrls(), Info.ATTACH_TYPE, bean.getId());

        if (workflow != null) {
            String stepName = workflowService.pass(workflow, creator, creator, new InfoProcess(), Info.WORKFLOW_TYPE,
                    bean.getId(), null, false);
            if (StringUtils.isNotBlank(stepName)) {
                // 审核中
                bean.setStatus(Info.AUDITING);
                detail.setStepName(stepName);
            } else if ("".equals(stepName)) {
                // 终审通过
                bean.setStatus(Info.NORMAL);
                detail.setStepName(null);
            }
        }
        updateHtml(bean, false);
        firePostSave(bean);
        return bean;
    }

    public Info update(Info bean, InfoDetail detail, Integer[] nodeIds, Integer[] specialIds, Integer[] viewGroupIds,
                       Integer[] viewOrgIds,Integer[]voteIds, Map<String, String> customs, Map<String, String> clobs, List<InfoImage> images,
                       List<InfoFile> files, Integer[] attrIds, Map<String, String> attrImages, String[] tagNames, Integer nodeId,
                       User operator, boolean pass, boolean isContribute) {
        if (detail == null) {
            // 允许更新时，不传入detail。
            detail = infoDetailService.get(bean.getId());
        }
        Site site = bean.getSite();
        try {
            extractImage(site, bean.getCreator().getId(), bean.getNode(), detail, images, clobs, attrIds, attrImages);
        } catch (Exception e) {
            logger.error("extract image error!", e);
        }
        if (StringUtils.isNotBlank(detail.getSmallImage())) {
            bean.setWithImage(true);
        } else {
            bean.setWithImage(false);
        }
        // 更新并审核
        if (pass) {
            String status = bean.getStatus();
            if (isContribute) {
                if (Info.DRAFT.equals(status) || Info.REJECTION.equals(status)) {
                    bean.setStatus(Info.CONTRIBUTION);
                }
            } else {
                // 审核中、草稿、投稿、采集、退稿可审核。
                if (Info.AUDITING.equals(status) || Info.DRAFT.equals(status) || Info.CONTRIBUTION.equals(status)
                        || Info.COLLECTED.equals(status) || Info.REJECTION.equals(status)) {
                    Workflow workflow = bean.getNode().getWorkflow();
                    User owner = bean.getCreator();
                    String stepName = workflowService.pass(workflow, owner, operator, new InfoProcess(),
                            Info.WORKFLOW_TYPE, bean.getId(), null, !Info.AUDITING.equals(status));
                    if (StringUtils.isNotBlank(stepName)) {
                        // 审核中
                        bean.setStatus(Info.AUDITING);
                        detail.setStepName(stepName);
                    } else if ("".equals(stepName)) {
                        // 终审通过
                        bean.setStatus(Info.NORMAL);
                        detail.setStepName(null);
                    }
                }
            }
        }else{
            bean.setStatus("1");
        }
        bean.applyDefaultValue();
//        bean.adjustStatus();
        if(bean.getNewsType()==null || (bean.getNewsType()!=null && bean.getNewsType().intValue()!=5 && bean.getNewsType().intValue()!=4)){
            if(bean.getDetail()==null ||bean.getDetail().getDisclosetype()==null){
                if(bean.getVideo()!=null || detail.getVideo()!=null){   //视频新闻
                    bean.setNewsType(3);
                }else if(bean.getFile()!=null || detail.getFile()!=null){ //音频新闻
                    bean.setNewsType(2);
                }else{
                    bean.setNewsType(1);
                }
            }
        }
        if(StringUtils.isNotBlank(bean.getLink())){
            bean.setNewsType(6);
        }
        bean = dao.save(bean);

        if (nodeId != null) {
            nodeService.derefer(bean.getNode());
            bean.setNode(nodeService.refer(nodeId));
        }
        bean.getCustoms().clear();
        if (customs != null) {
            bean.getCustoms().putAll(customs);
        }
        bean.getClobs().clear();
        if (clobs != null) {
            sanitizeClob(clobs);
            bean.getClobs().putAll(clobs);
        }
        bean.getImages().clear();
        if (!CollectionUtils.isEmpty(images)) {
            bean.getImages().addAll(images);
        }
        bean.getFiles().clear();
        if (!CollectionUtils.isEmpty(files)) {
            bean.getFiles().addAll(files);
        }

        infoDetailService.update(detail, bean);
        infoAttrService.update(bean, attrIds, attrImages);
        infoNodeService.update(bean, nodeIds, nodeId);
        infoTagService.update(bean, tagNames);
        infoSpecialService.update(bean, specialIds);
        infoVoteService.update(bean,voteIds);
        infoMemberGroupService.update(bean, viewGroupIds);
        infoOrgService.update(bean, viewOrgIds);
        attachmentRefService.update(bean.getAttachUrls(), Info.ATTACH_TYPE, bean.getId());
        updateHtml(bean, false);

        firePostUpdate(bean);
        return bean;
    }

    public List<Info> updateInfoRef(Integer[] infoIds, Integer nodeId,Integer orderId) {
        List<Info> infos=null;
        if(infoIds==null || infoIds.length==0 || nodeId==null){
             return null;
        }
        infos=new ArrayList<Info>();
        for(Integer infoId:infoIds){
            Info info=dao.findOne(infoId);
            dao.save(info);
            infoNodeService.updateRef(info, new Integer[]{nodeId}, nodeId,orderId);
            infos.add(info);
        }
        return infos;
    }

    @Override
    public void updatePublishDate(Integer infoId, Date publishDate) {
         dao.updatePublishDate(infoId,publishDate);
    }

    @Override
    public void updateOrder(Integer order,Integer infoId) {
        dao.updateOrder(order,infoId);
    }

    @Override
    public void updateSelect(Integer select,Integer infoId) {
        dao.updateSelect(select,infoId);
    }

    @Override
    public Info updateRefLive(Info bean) {
        return dao.save(bean);
    }

    @Override
    public void pubCityInfo(List<Info> beans, Integer pubCityNode,Integer userId) {
       if(beans==null || beans.size()==0){
           return;
       }
       Node node=nodeQueryService.get(pubCityNode);
       Site site=node.getSite();
       for(Info info:beans){
           Info bean=new Info();
           //判断当前新闻是否存在直播盐都市州圈，如果存在，则更新，否则新增
           List<Info> sourceinfos=dao.findByTitleAndNode(info.getTitle(),site.getId(),node.getId());
           if(sourceinfos!=null && sourceinfos.size()>0){    //存在
              for(Info sourceInfo:sourceinfos){

                  InfoDetail detail=sourceInfo.getDetail();
                  detail.setTitle(info.getDetail().getTitle());
                  detail.setLink(info.getDetail().getLink());
                  detail.setSmallImage(info.getDetail().getSmallImage());
                  detail.setAllowComment(info.getDetail().getAllowComment());
                  detail.setAuthor(info.getDetail().getAuthor());
                  detail.setFile(info.getDetail().getFile());
                  detail.setFileLength(info.getDetail().getFileLength());
                  detail.setFileName(info.getDetail().getFileName());
                  detail.setHtml(info.getDetail().getHtml());
                  detail.setFullTitle(info.getDetail().getFullTitle());
                  detail.setLargeImage(info.getDetail().getLargeImage());
                  detail.setLinkAddress(info.getDetail().getLinkAddress());
                  detail.setMetaDescription(info.getDetail().getMetaDescription());
                  detail.setSource(info.getDetail().getSource());
                  detail.setSourceUrl(info.getDetail().getSourceUrl());
                  detail.setVideo(info.getVideo());
                  detail.setVideoName(info.getVideoName());
                  detail.setVideoLength(info.getVideoLength());
                  detail.setVideoTime(info.getVideoTime());

                  sourceInfo.setIswatch(info.getIswatch());
                  sourceInfo.setPriority(info.getPriority());
                  sourceInfo.setHighlightText(info.getHighlightText());
                  sourceInfo.setOffDate(info.getOffDate());
                  sourceInfo.setText(info.getText());
                  sourceInfo.setPublishDate(info.getPublishDate());

                  sourceInfo.setSite(site);
                  User creator = userService.get(userId);
                  sourceInfo.setCreator(creator);
                  sourceInfo.setOrg(creator.getOrg());
                  sourceInfo.setNode(node);
                  sourceInfo.setWithImage(info.getWithImage());

                  sourceInfo.setStatus("A");
                  sourceInfo.applyDefaultValue();
                  sourceInfo.setNewsType(info.getNewsType());

                  sourceInfo = dao.save(sourceInfo);
                  infoDetailService.save(detail, sourceInfo);
                  // 将InfoBuffer对象一并保存，以免在网页浏览时再保存，导致并发保存报错
//                  infoBufferService.save(new InfoBuffer(), sourceInfo);
                  infoNodeService.update(sourceInfo,null, node.getId());
                  String[] tagNames = splitTagKeywords(info.getTagKeywords());
                  infoTagService.update(sourceInfo, tagNames);
                  htmlService.makeInfo(sourceInfo.getId());
                  firePostUpdate(sourceInfo);
              }
           }else{                                //不存在
               InfoDetail detail=new InfoDetail();
               detail.setTitle(info.getDetail().getTitle());
               detail.setLink(info.getDetail().getLink());
               detail.setSmallImage(info.getDetail().getSmallImage());
               detail.setAllowComment(info.getDetail().getAllowComment());
               detail.setAuthor(info.getDetail().getAuthor());
               detail.setFile(info.getDetail().getFile());
               detail.setFileLength(info.getDetail().getFileLength());
               detail.setFileName(info.getDetail().getFileName());
               detail.setHtml(info.getDetail().getHtml());
               detail.setFullTitle(info.getDetail().getFullTitle());
               detail.setLargeImage(info.getDetail().getLargeImage());
               detail.setLinkAddress(info.getDetail().getLinkAddress());
               detail.setMetaDescription(info.getDetail().getMetaDescription());
               detail.setSource(info.getDetail().getSource());
               detail.setSourceUrl(info.getDetail().getSourceUrl());
               detail.setVideo(info.getVideo());
               detail.setVideoName(info.getVideoName());
               detail.setVideoLength(info.getVideoLength());
               detail.setVideoTime(info.getVideoTime());

               bean.setIswatch(info.getIswatch());
               bean.setPriority(info.getPriority());
               bean.setHighlightText(info.getHighlightText());
               bean.setOffDate(info.getOffDate());
               bean.setText(info.getText());
               bean.setPublishDate(info.getPublishDate());

               bean.setSite(site);
               User creator = userService.get(userId);
               bean.setCreator(creator);
               bean.setOrg(creator.getOrg());
               bean.setNode(node);
//           bean.setCustoms(info.getCustoms());
//           bean.setClobs(info.getClobs());
//           bean.setImages(info.getImages());
//           bean.setFiles(info.getFiles());
//           try {
//               extractImage(bean.getSite(), creatorId, node, detail, images, clobs, attrIds, attrImages);
//           } catch (Exception e) {
//               logger.error("extract image error!", e);
//           }
//
               bean.setWithImage(info.getWithImage());

               bean.setStatus("A");
               bean.applyDefaultValue();
               bean.setNewsType(info.getNewsType());

               bean = dao.save(bean);
               infoDetailService.save(detail, bean);
           // 将InfoBuffer对象一并保存，以免在网页浏览时再保存，导致并发保存报错
               infoBufferService.save(new InfoBuffer(), bean);
//           infoAttrService.update(bean, attrIds, attrImages);
               infoNodeService.update(bean,null, node.getId());
               String[] tagNames = splitTagKeywords(info.getTagKeywords());
               infoTagService.update(bean, tagNames);
//           Integer[] specialIds=null;
//           if(info.getSpecials()!=null && info.getSpecials().size()>0){
//             for(int i=0;i<info.getSpecials().size();i++){
//               specialIds[i]=info.getSpecials().get(i).getId();
//             }
//           }
//           Integer[] voteIds=null;
//           if(info.getVotes()!=null && info.getVotes().size()>0){
//               for(int i=0;i<info.getVotes().size();i++){
//                   voteIds[i]=info.getVotes().get(i).getId();
//               }
//           }
//           infoSpecialService.update(bean, specialIds);
//           infoVoteService.update(bean,voteIds);
//           infoMemberGroupService.update(bean, viewGroupIds);
//           infoOrgService.update(bean, viewOrgIds);
//           attachmentRefService.update(bean.getAttachUrls(), Info.ATTACH_TYPE, bean.getId());
               htmlService.makeInfo(bean.getId());
               firePostSave(bean);
           }
           site.setGenCityNode("0");
           siteService.update(site);
       }

    }

    @Override
    public void genCityNodeTiming(Integer siteId) {
        System.out.println("--------city runing start---------");
        if(siteId==null){
          return;
        }
        Site site=siteService.get(siteId);
        if(site==null || site.getGenCityNode()==null){
          return;
        }
        if("0".equals(site.getGenCityNode())){
            logger.info("------定时生成市州圈开始--------");
            Integer[] nodeIds=getNodeIdsByFlag(Constants.MODEL_FLAG_CITY_STATE,site.getId());
            if(nodeIds!=null && nodeIds.length>0){
                Node parentNode=nodeQueryService.get(nodeIds[0]);
                htmlService.makeNode(parentNode.getId());
                site.setGenCityNode("1");
                siteService.update(site);
            }
            logger.info("------定时生成市州圈结束--------");
        }
        System.out.println("--------city runing end---------");
    }
    private Integer[] getNodeIdsByFlag(String modelFlag,Integer siteId) {
        Integer [] nodeIds=null;
        Map<String,String[]> paramMap=new HashMap<String,String[]>();
        paramMap.put("EQ_flag",new String[]{modelFlag});
        List<Model> models=modelService.findList(siteId,null,paramMap,null);

        paramMap=new HashMap<String,String[]>();
        String[] idsStr;
        if(models!=null && models.size()>0){
            idsStr=new String[models.size()];
            for(int i=0;i<models.size();i++){
                idsStr[i]=models.get(i).getId().toString();
            }
            paramMap.put("EQ_nodeModel.id",idsStr);
        }
        Sort paramSort=new Sort(Sort.Direction.ASC, "treeNumber", "id");
        List<Node>  currentNodeList=nodeQueryService.findList(siteId,null,
                null,null,true,
                paramMap, paramSort);
        if(currentNodeList!=null){
            nodeIds=new Integer[currentNodeList.size()];
            for(int i=0;i<currentNodeList.size();i++){
                nodeIds[i]=(currentNodeList.get(i).getId());
            }
        }
        return  nodeIds;
    }

    private void extractImage(Site site, Integer userId, Node node, InfoDetail detail, List<InfoImage> images,
                              Map<String, String> clobs, Integer[] attrIds, Map<String, String> attrImages) throws IOException {
        PublishPoint point = site.getUploadsPublishPoint();
        String urlPrefix = point.getUrlPrefix();
        String srcImage;
        // 内容图
        srcImage = detail.getLargeImage();
        if (!StringUtils.startsWith(srcImage, urlPrefix) && images != null) {
            // 图集
            for (InfoImage infoImage : images) {
                srcImage = infoImage.getImage();
                if (StringUtils.startsWith(srcImage, urlPrefix)) {
                    break;
                } else {
                    srcImage = null;
                }
            }
        }
        if (!StringUtils.startsWith(srcImage, urlPrefix) && clobs != null) {
            // 正文图
            for (String textImage : Info.getTextImages(clobs)) {
                if (StringUtils.startsWith(textImage, urlPrefix)) {
                    srcImage = textImage;
                    break;
                }
            }
        }
        if (!StringUtils.startsWith(srcImage, urlPrefix)) {
            return;
        }
        srcImage = srcImage.substring(urlPrefix.length());

        FileHandler fileHandler = point.getFileHandler(pathResolver);
        String formatName = fileHandler.getFormatName(srcImage);
        if (StringUtils.isBlank(formatName)) {
            return;
        }
        File src = fileHandler.getFile(srcImage);
        BufferedImage buff = ImageIO.read(src);
        // 太小图片不获取
        if (buff.getWidth() < 100 || buff.getHeight() < 100) {
            return;
        }

        String extension = FilenameUtils.getExtension(srcImage).toLowerCase();
        boolean scale, exact;
        String imageWidth, imageHeight;
        Integer width, height;
        String targetImage;
        Model model = node.getInfoModel();
        if (StringUtils.isBlank(detail.getSmallImage())) {
            ModelField field = model.getField("smallImage");
            if (field != null) {
                Map<String, String> customs = field.getCustoms();
                scale = !"false".equals(customs.get("imageScale"));
                exact = "true".equals(customs.get("imageExact"));
                imageWidth = customs.get("imageWidth");
                imageHeight = customs.get("imageHeight");
                if (StringUtils.isNotBlank(imageWidth)) {
                    width = Integer.parseInt(imageWidth);
                } else {
                    width = null;
                }
                if (StringUtils.isNotBlank(imageHeight)) {
                    height = Integer.parseInt(imageHeight);
                } else {
                    height = null;
                }
                // 复制图片，压缩，得到新图片地址。
                targetImage = uploadHandler.copyImage(src, extension, formatName, site, scale, exact, width, height,
                        null, null, null, null, null, userId, site.getId());
                detail.setSmallImage(targetImage);
            }
        }
        if (ArrayUtils.isNotEmpty(attrIds)) {
            Attribute attr;
            Integer attrId;
            String attrImage;
            for (Integer i = 0, len = attrIds.length; i < len; i++) {
                attrId = attrIds[i];
                attrImage = attrImages.get(attrId.toString());
                attr = attributeService.get(attrId);
                if (attr.getWithImage() && StringUtils.isBlank(attrImage)) {
                    scale = true;
                    width = attr.getImageWidth();
                    height = attr.getImageHeight();
                    exact = true;
                    targetImage = uploadHandler.copyImage(src, extension, formatName, site, scale, exact, width,
                            height, null, null, null, null, null, userId, site.getId());
                    attrImages.put(attrId.toString(), targetImage);
                }
            }
        }
    }

    public List<Info> pass(Integer[] ids, Integer userId, String opinion) {
        Info info;
        InfoDetail detail;
        Workflow workflow;
        User owner;
        User operator = userService.get(userId);
        List<Info> infos = new ArrayList<Info>();
        for (Integer id : ids) {
            info = dao.findOne(id);
            detail = info.getDetail();
            String status = info.getStatus();
            // 审核中、草稿、投稿、采集、退稿可审核。
            if (Info.AUDITING.equals(status) || Info.DRAFT.equals(status) || Info.CONTRIBUTION.equals(status)
                    || Info.COLLECTED.equals(status) || Info.REJECTION.equals(status)) {
                workflow = info.getNode().getWorkflow();
                owner = info.getCreator();
                String stepName = workflowService.pass(workflow, owner, operator, new InfoProcess(),
                        Info.WORKFLOW_TYPE, info.getId(), null, !Info.AUDITING.equals(status));
                if (StringUtils.isNotBlank(stepName)) {
                    // 审核中
                    info.setStatus(Info.AUDITING);
                    detail.setStepName(stepName);
                } else if ("".equals(stepName)) {
                    // 终审通过
                    info.setStatus(Info.NORMAL);
                    detail.setStepName(null);
                    info.adjustStatus();
                    if(Info.CONTRIBUTION.equals(status)){
                        info.setIsUse("1");
                    }
                }
            }
            infos.add(info);
        }
        updateHtml(infos, false);
        firePostPass(infos);
        return infos;
    }

    public List<Info> reject(Integer[] ids, Integer userId, String opinion, boolean rejectEnd) {
        Info info;
        InfoDetail detail;
        Workflow workflow;
        User owner;
        User operator = userService.get(userId);
        List<Info> infos = new ArrayList<Info>();
        for (Integer id : ids) {
            info = dao.findOne(id);
            detail = info.getDetail();
            String status = info.getStatus();
            if (Info.CONTRIBUTION.equals(status)) {
                // 投稿退回。不需要经过工作流。
                info.setStatus(Info.REJECTION);
            } else if (Info.AUDITING.equals(status) || Info.NORMAL.equals(status) || Info.TOBE_PUBLISH.equals(status)
                    || Info.EXPIRED.equals(status)) {
                // 审核中、已发布、待发布、已过期可审核退回。
                workflow = info.getNode().getWorkflow();
                owner = info.getCreator();
                String stepName = workflowService.reject(workflow, owner, operator, new InfoProcess(),
                        Info.WORKFLOW_TYPE, info.getId(), opinion, rejectEnd);
                if (StringUtils.isNotBlank(stepName)) {
                    // 审核中
                    info.setStatus(Info.AUDITING);
                    detail.setStepName(stepName);
                } else if ("".equals(stepName)) {
                    // 退稿
                    info.setStatus(Info.REJECTION);
                    detail.setStepName(null);
                }
                info.adjustStatus();
            }
            infos.add(info);
        }
        updateHtml(infos, false);
        firePostReject(infos);
        return infos;
    }

    Info entity;
    public List<Info> move(Integer[] ids, Integer nodeId) {
        Integer[] nodeIds;
        List<Info> infos = new ArrayList<Info>();
        for (Integer id : ids) {
            entity = dao.findOne(id);
            nodeService.derefer(entity.getNode());
            entity.setNode(nodeService.refer(nodeId));
            nodeIds = entity.getNodeIdsExcludeMain();
            infoNodeService.update(entity, nodeIds, nodeId);
        }
        updateHtml(infos, false);
        firePostMove(infos);
        return infos;
    }

    public int moveByNodeId(Collection<Integer> nodeIds, Integer nodeId) {
        int count = dao.moveByNodeId(nodeIds, nodeId);
        infoNodeService.moveByNodeId(nodeIds, nodeId);
        return count;
    }

    /**
     * 逻辑删除
     */
    public List<Info> logicDelete(Integer[] ids) {
        List<Info> infos = new ArrayList<Info>(ids.length);
        Info bean;
        for (int i = 0; i < ids.length; i++) {
            bean = dao.findOne(ids[i]);
            if (bean != null) {
                bean.setStatus(Info.DELETED);
                infos.add(bean);
            }
        }
        updateHtml(infos, false);
        firePostLogicDelete(infos);
        return infos;
    }

    /**
     * 恢复
     */
    public List<Info> recall(Integer[] ids) {
        List<Info> infos = new ArrayList<Info>(ids.length);
        Info bean;
        for (int i = 0; i < ids.length; i++) {
            bean = dao.findOne(ids[i]);
            if (bean != null && bean.getStatus().equals(Info.DELETED)) {
                bean.setStatus(Info.REJECTION);
                infos.add(bean);
            }
        }
        updateHtml(infos, false);
        firePostLogicDelete(infos);
        return infos;
    }

    /**
     * 归档
     */
    public List<Info> archive(Integer[] ids) {
        List<Info> infos = new ArrayList<Info>(ids.length);
        Info bean;
        for (int i = 0; i < ids.length; i++) {
            bean = dao.findOne(ids[i]);
            if (bean != null) {
                bean.setStatus(Info.ARCHIVE);
                infos.add(bean);
            }
        }
        updateHtml(infos, false);
        firePostLogicDelete(infos);
        return infos;
    }

    /**
     * 反归档
     */
    public List<Info> antiArchive(Integer[] ids) {
        List<Info> infos = new ArrayList<Info>(ids.length);
        Info bean;
        for (int i = 0; i < ids.length; i++) {
            bean = dao.findOne(ids[i]);
            if (bean != null && bean.getStatus().equals(Info.ARCHIVE)) {
                bean.setStatus(Info.REJECTION);
                infos.add(bean);
            }
        }
        updateHtml(infos, false);
        firePostLogicDelete(infos);
        return infos;
    }

    private Info doDelete(Integer id) {
        Info entity = dao.findOne(id);
        if (entity != null) {
            // 删除Tag引用数
            for (InfoTag infoTag : entity.getInfoTags()) {
                infoTag.getTag().derefer();
            }
            commentService.deleteByFtypeAndFid(Info.COMMENT_TYPE, id);
            nodeService.derefer(entity.getNode());
            attachmentRefService.delete(Info.ATTACH_TYPE, entity.getId());
            PInfo.deleteHtml(entity, pathResolver);
            dao.delete(entity);
        }
        return entity;
    }

    public Info delete(Integer id) {
        firePreDelete(new Integer[]{id});
        Info bean = doDelete(id);
        if (bean != null) {
            List<Info> beans = new ArrayList<Info>();
            bean.setStatus(Info.CLEAR);
            beans.add(bean);
            firePostDelete(beans);
        }
        updateHtml(bean, true);
//        updateHtmlThread(bean, true);
        return bean;
    }

    public List<Info> delete(Integer[] ids) {
        firePreDelete(ids);
        List<Info> beans = new ArrayList<Info>(ids.length);
        Info bean;
        for (int i = 0; i < ids.length; i++) {
            bean = doDelete(ids[i]);
            if (bean != null) {
                bean.setStatus(Info.CLEAR);
                beans.add(bean);
            }
        }
        updateHtml(beans, true);
        firePostDelete(beans);
        return beans;
    }

    public int publish(Integer siteId) {
        return dao.publish(siteId, new Date());
    }

    public int tobePublish(Integer siteId) {
        return dao.tobePublish(siteId, new Date());
    }

    public int expired(Integer siteId) {
        return dao.expired(siteId, new Date());
    }

    private void updateHtml(Info bean, boolean toDelete) {
        Set<Info> beans = new HashSet<Info>();
        beans.add(bean);
        updateHtml(beans, toDelete);
    }

//    @Override
//    public List queryInfo(Integer id) {
//        return dao.queryInfo(id);
//    }

    private void updateHtml(Collection<Info> beans, boolean toDelete) {
        Set<Info> infos = new HashSet<Info>();
        Set<Node> nodes = new HashSet<Node>();
        Node node;
        for (Info bean : beans) {
            node = bean.getNode();
            node.updateHtmlStatus();
            nodes.add(node);

            bean.updateHtmlStatus();
            if (bean.getNode().getStaticMethodOrDef() != Node.STATIC_MANUAL) {
                infos.add(bean);
            }
//            Integer id = bean.getId();
//            Info next = query.findNext(id, false);
//            Info prev = query.findPrev(id, false);
//            if (next != null) {
//                next.updateHtmlStatus();
//                if (next.getNode().getStaticMethodOrDef() != Node.STATIC_MANUAL) {
//                    infos.add(next);
//                }
//            }
//            if (prev != null) {
//                prev.updateHtmlStatus();
//                if (prev.getNode().getStaticMethodOrDef() != Node.STATIC_MANUAL) {
//                    infos.add(prev);
//                }
//            }
        }
        for (Info i : infos) {
            if (toDelete) {
                htmlService.deleteInfo(i);
            } else {
                htmlService.makeInfo(i);
            }
        }
//        for (Node n : nodes) {
//            htmlService.makeNode(n,null);
//        }
    }

//    public void updateHtmlThread(final Integer infoId, final boolean toDelete, final String method) {
//        new Thread() {
//            @Override
//            public void run() {
//                try {
//                    // 等待主线程结束，提交事务后，再运行。
//                    Thread.sleep(2000);
//                } catch (InterruptedException e) {
//                    logger.error(null, e);
//                }
//                Info result=htmlService.generationInfo(infoId,toDelete);
//                if(method!=null && "firePostSave".equals(method)){
//                    firePostSave(result);
//                }else if(method!=null && "firePostUpdate".equals(method)){
//                    firePostUpdate(result);
//                }
//
//            }
//        }.start();
//    }
//
//    public void batchupdateHtmlThread(final List<Integer> beanids,final boolean toDelete, final String method) {
//        new Thread() {
//            @Override
//            public void run() {
//                try {
//                    // 等待主线程结束，提交事务后，再运行。
//                    Thread.sleep(2000);
//                } catch (InterruptedException e) {
//                    logger.error(null, e);
//                }
//                List<Info> results=htmlService.generationInfo(beanids,toDelete);
//                if("firePostPass".equals(method)){
//                    firePostPass(results);
//                }
//
//            }
//        }.start();
//    }

//    @JmsListener(destination = "api.sendAnchorTimeLine")
//    public void receiveQueue(String text) {
//
//            if(StringUtils.isBlank(text)){
//                return;
//            }
//            JSONObject jsonObject=JSONObject.parseObject(text);
//            if(!jsonObject.containsKey("nodeId") || !jsonObject.containsKey("siteId")){
//                return;
//            }
//            Integer paramNodeId=jsonObject.getInteger("nodeId");
//            Integer paramSiteId=jsonObject.getInteger("siteId");
//            if(paramNodeId==null || paramSiteId==null){
//                return;
//            }
//
//            Node node=nodeQueryService.get(nodeQueryService.get(paramNodeId).getParent().getId());
//            //顶级主播栏目id
//            Integer topNodeId=node.getParent().getId();
//
//            try {
//                htmlService.makeInfo(paramSiteId, topNodeId, true, null, false, null, 200);
//                htmlService.makeNode(paramSiteId, topNodeId, true, null, false, null, 200,null);
//            } catch (IOException e) {
//                e.printStackTrace();
//            } catch (TemplateException e) {
//                e.printStackTrace();
//            }
//
//    }

    public void pubCityInfoQueue(String text) {

        try {
            if(StringUtils.isBlank(text)){
                return;
            }
            JSONArray  jsonArray= JSONArray.parseArray(text);
            if(jsonArray==null || jsonArray.size()==0){
                return;
            }
            Site site=null;
            Node node=null;
            for(int i=0;i<jsonArray.size();i++){
                Info bean=new Info();
                JSONObject jsonObject=jsonArray.getJSONObject(i);

                Integer nodeId=jsonObject.getInteger("nodeId");
                String title=jsonObject.getString("title");
                node=nodeQueryService.get(nodeId);
                site=siteService.get(node.getSite().getId());
                Org org=orgService.get(site.getOrg().getId());
                //判断当前新闻是否存在直播盐都市州圈，如果存在，则更新，否则新增
                List<Info> sourceinfos=dao.findByTitleAndNode(title,site.getId(),node.getId());
                if(sourceinfos!=null && sourceinfos.size()>0){    //存在
                    for(Info sourceInfo:sourceinfos){

                        InfoDetail detail=sourceInfo.getDetail();
                        detail.setTitle(title);
                        detail.setLink(jsonObject.getString("link"));
                        detail.setSmallImage(jsonObject.getString("smallImage"));
                        detail.setAllowComment(jsonObject.getBoolean("allowComment"));
                        detail.setAuthor(jsonObject.getString("author"));
                        detail.setFile(jsonObject.getString("file"));
                        detail.setFileLength(jsonObject.getLong("fileLength"));
                        detail.setFileName(jsonObject.getString("fileName"));
                        detail.setHtml(jsonObject.getString("html"));
                        detail.setFullTitle(jsonObject.getString("fullTitle"));
                        detail.setLargeImage(jsonObject.getString("largeImage"));
                        detail.setLinkAddress(jsonObject.getString("linkAddress"));
                        detail.setMetaDescription(jsonObject.getString("metaDescription"));
                        detail.setSource(jsonObject.getString("source"));
                        detail.setSourceUrl(jsonObject.getString("sourceUrl"));
                        detail.setVideo(jsonObject.getString("video"));
                        detail.setVideoName(jsonObject.getString("videoName"));
                        detail.setVideoLength(jsonObject.getLong("videoLength"));
                        detail.setVideoTime(jsonObject.getString("videoTime"));

                        sourceInfo.setIswatch(jsonObject.getInteger("iswatch"));
                        sourceInfo.setPriority(jsonObject.getInteger("priority"));
                        sourceInfo.setHighlightText(jsonObject.getString("highlightText"));
                        sourceInfo.setOffDate(jsonObject.getDate("offDate"));
                        sourceInfo.setText(jsonObject.getString("text"));
                        sourceInfo.setPublishDate(jsonObject.getDate("publishDate"));

                        sourceInfo.setSite(site);
                        sourceInfo.setCreator(node.getCreator());
                        sourceInfo.setOrg(site.getOrg());
                        sourceInfo.setNode(node);
                        sourceInfo.setWithImage(jsonObject.getBoolean("withImage"));

                        sourceInfo.setStatus(jsonObject.getString("status"));
                        sourceInfo.applyDefaultValue();
                        sourceInfo.setNewsType(jsonObject.getInteger("newsType"));

                        sourceInfo = dao.save(sourceInfo);
                        infoDetailService.save(detail, sourceInfo);
                        // 将InfoBuffer对象一并保存，以免在网页浏览时再保存，导致并发保存报错
                        //                  infoBufferService.save(new InfoBuffer(), sourceInfo);
                        infoNodeService.update(sourceInfo,null, node.getId());
                        String[] tagNames = splitTagKeywords(jsonObject.getString("tagKeywords"));
                        infoTagService.update(sourceInfo, tagNames);
                        htmlService.makeInfo(sourceInfo.getId());
                        firePostUpdate(sourceInfo);
                    }
                }else{
                    InfoDetail detail=new InfoDetail();
                    detail.setTitle(title);
                    detail.setLink(jsonObject.getString("link"));
                    detail.setSmallImage(jsonObject.getString("smallImage"));
                    detail.setAllowComment(jsonObject.getBoolean("allowComment"));
                    detail.setAuthor(jsonObject.getString("author"));
                    detail.setFile(jsonObject.getString("file"));
                    detail.setFileLength(jsonObject.getLong("fileLength"));
                    detail.setFileName(jsonObject.getString("fileName"));
                    detail.setHtml(jsonObject.getString("html"));
                    detail.setFullTitle(jsonObject.getString("fullTitle"));
                    detail.setLargeImage(jsonObject.getString("largeImage"));
                    detail.setLinkAddress(jsonObject.getString("linkAddress"));
                    detail.setMetaDescription(jsonObject.getString("metaDescription"));
                    detail.setSource(jsonObject.getString("source"));
                    detail.setSourceUrl(jsonObject.getString("sourceUrl"));
                    detail.setVideo(jsonObject.getString("video"));
                    detail.setVideoName(jsonObject.getString("videoName"));
                    detail.setVideoLength(jsonObject.getLong("videoLength"));
                    detail.setVideoTime(jsonObject.getString("videoTime"));
                    bean.setIswatch(jsonObject.getInteger("iswatch"));
                    bean.setPriority(jsonObject.getInteger("priority"));
                    bean.setHighlightText(jsonObject.getString("highlightText"));
                    bean.setOffDate(jsonObject.getDate("offDate"));
                    bean.setText(jsonObject.getString("text"));
                    bean.setPublishDate(jsonObject.getDate("publishDate"));
                    bean.setSite(site);   //站点
                    bean.setCreator(node.getCreator());
                    bean.setOrg(org);
                    bean.setNode(node);            //栏目
                    bean.setWithImage(jsonObject.getBoolean("withImage"));
                    bean.setStatus(jsonObject.getString("status"));
                    bean.setNewsType(jsonObject.getInteger("newsType"));
                    bean.applyDefaultValue();
                    bean = dao.save(bean);
                    infoDetailService.save(detail, bean);
                    infoNodeService.update(bean,null, node.getId());
                    String[] tagNames = splitTagKeywords(jsonObject.getString("tagKeywords"));
                    infoTagService.update(bean, tagNames);
                    htmlService.makeInfo(bean.getId());
                    firePostSave(bean);
                }

            }
//            htmlGenerator.makeNode(site.getId(), node.getId(),node.getName(), true, node.getCreator().getId(),null);
            htmlService.makeNode(site.getId(), node.getId(), true, null, false, null, 200,null);
            site.setGenCityNode("0");
            siteService.update(site);
            logger.info(node.getName()+"-----:发文！");
        } catch (Exception e) {
            e.printStackTrace();
        }


    }

    public void saveInfoToCityNode(String cityNodes,Info sourceInfo) {

        try {
            String[] citys=null;
            if(StringUtils.isNotBlank(cityNodes)){
                citys=cityNodes.split(",");
            }
            if(citys!=null && citys.length>0 && sourceInfo!=null){
                for(String cityIdStr:citys){
                    Info bean=new Info();
                    Integer cityId=Integer.parseInt(cityIdStr);
                    Node cityNode=nodeQueryService.get(cityId);

                    //根据新闻标题 栏目 站点 判断当前新闻是否存在市州栏目，如果不存在，则新增
                    List<Info> sourceinfos=dao.findByTitleAndNode(sourceInfo.getDetail().getTitle(),sourceInfo.getSite().getId(),cityId);

                    if(sourceinfos!=null && sourceinfos.size()>0){
                        continue;
                    }
                    InfoDetail cityDetail=new InfoDetail();
                    cityDetail.setTitle(sourceInfo.getDetail().getTitle());
                    cityDetail.setLink(sourceInfo.getDetail().getLink());
                    cityDetail.setSmallImage(sourceInfo.getDetail().getSmallImage());
                    cityDetail.setAllowComment(sourceInfo.getDetail().getAllowComment());
                    cityDetail.setAuthor(sourceInfo.getDetail().getAuthor());
                    cityDetail.setFile(sourceInfo.getDetail().getFile());
                    cityDetail.setFileLength(sourceInfo.getDetail().getFileLength());
                    cityDetail.setFileName(sourceInfo.getDetail().getFileName());
                    cityDetail.setHtml(sourceInfo.getDetail().getHtml());
                    cityDetail.setFullTitle(sourceInfo.getDetail().getFullTitle());
                    cityDetail.setLargeImage(sourceInfo.getDetail().getLargeImage());
                    cityDetail.setLinkAddress(sourceInfo.getDetail().getLinkAddress());
                    cityDetail.setMetaDescription(sourceInfo.getDetail().getMetaDescription());
                    cityDetail.setSource(sourceInfo.getDetail().getSource());
                    cityDetail.setSourceUrl(sourceInfo.getDetail().getSourceUrl());
                    cityDetail.setVideo(sourceInfo.getVideo());
                    cityDetail.setVideoName(sourceInfo.getVideoName());
                    cityDetail.setVideoLength(sourceInfo.getVideoLength());
                    cityDetail.setVideoTime(sourceInfo.getVideoTime());
                    bean.setIswatch(sourceInfo.getIswatch());
                    bean.setPriority(sourceInfo.getPriority());
                    bean.setHighlightText(sourceInfo.getHighlightText());
                    bean.setOffDate(sourceInfo.getOffDate());
                    bean.setText(sourceInfo.getText());
                    bean.setPublishDate(sourceInfo.getPublishDate());
                    bean.setSite(sourceInfo.getSite());   //站点
                    bean.setCreator(sourceInfo.getCreator());
                    bean.setOrg(sourceInfo.getOrg());
                    bean.setNode(cityNode);            //栏目
                    bean.setWithImage(sourceInfo.getWithImage());
                    bean.setStatus(sourceInfo.getStatus());
                    bean.setNewsType(sourceInfo.getNewsType());
                    bean.setRealviews(sourceInfo.getRealviews());
                    bean.setViews(sourceInfo.getViews());
                    bean.applyDefaultValue();
                    bean = dao.save(bean);
                    infoDetailService.save(cityDetail, bean);
                    infoNodeService.update(bean,null, cityId);
                    String[] tagNames = splitTagKeywords(sourceInfo.getTagKeywords());
                    infoTagService.update(bean, tagNames);
                    firePostSave(bean);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private void sanitizeClob(Map<String, String> clobs) {
        // if (clobs == null) {
        // return;
        // }
        // for (Entry<String, String> entry : clobs.entrySet()) {
        // String v = entry.getValue();
        // if (v != null) {
        // entry.setValue(policyFactory.sanitize(v));
        // }
        // }
    }

    public void preUserDelete(Integer[] ids) {
        if (ArrayUtils.isNotEmpty(ids)) {
            List<Integer> idList = Arrays.asList(ids);
            if (dao.countByUserId(idList) > 0) {
                throw new DeleteException("info.management");
            }
            List<Info> beans = dao.findByCreatorIdIn(idList);
            for (Info bean : beans) {
                delete(bean.getId());
            }
        }
    }

    public void preNodeDelete(Integer[] ids) {
        if (ArrayUtils.isNotEmpty(ids)) {
            List<Integer> idList = Arrays.asList(ids);
            if (dao.countByNodeIdNotDeleted(idList) > 0) {
                throw new DeleteException("info.management");
            }
            List<Info> beans = dao.findByNodeIdIn(idList);
            for (Info bean : beans) {
                delete(bean.getId());
            }
        }
    }

    public void preOrgDelete(Integer[] ids) {
        if (ArrayUtils.isNotEmpty(ids)) {
            List<Integer> idList = Arrays.asList(ids);
            if (dao.countByOrgIdNotDeleted(idList) > 0) {
                throw new DeleteException("info.management");
            }
            List<Info> beans = dao.findByOrgIdIn(idList);
            for (Info bean : beans) {
                delete(bean.getId());
            }
        }
    }

    public void preSiteDelete(Integer[] ids) {
        if (ArrayUtils.isNotEmpty(ids)) {
            List<Integer> idList = Arrays.asList(ids);
            if (dao.countBySiteIdNotDeleted(idList) > 0) {
                throw new DeleteException("info.management");
            }
            List<Info> beans = dao.findBySiteIdIn(idList);
            for (Info bean : beans) {
                delete(bean.getId());
            }
        }
    }

    private void firePostSave(Info bean) {
        if (!CollectionUtils.isEmpty(listeners)) {
            for (InfoListener listener : listeners) {
                listener.postInfoSave(bean);
            }
        }
    }

    private void firePostUpdate(Info bean) {
        if (!CollectionUtils.isEmpty(listeners)) {
            for (InfoListener listener : listeners) {
                listener.postInfoUpdate(bean);
            }
        }
    }

    private void firePostPass(List<Info> beans) {
        if (!CollectionUtils.isEmpty(listeners)) {
            for (InfoListener listener : listeners) {
                listener.postInfoPass(beans);
            }
        }
    }

    private void firePostReject(List<Info> beans) {
        if (!CollectionUtils.isEmpty(listeners)) {
            for (InfoListener listener : listeners) {
                listener.postInfoReject(beans);
            }
        }
    }

    private void firePostMove(List<Info> beans) {
        if (!CollectionUtils.isEmpty(listeners)) {
            for (InfoListener listener : listeners) {
                listener.postInfoMove(beans);
            }
        }
    }

    private void firePostLogicDelete(List<Info> beans) {
        if (!CollectionUtils.isEmpty(listeners)) {
            for (InfoListener listener : listeners) {
                listener.postInfoLogicDelete(beans);
            }
        }
    }

    private void firePostDelete(List<Info> beans) {
        if (!CollectionUtils.isEmpty(listeners)) {
            for (InfoListener listener : listeners) {
                listener.postInfoDelete(beans);
            }
        }
    }

    private void firePreDelete(Integer[] ids) {
        if (!CollectionUtils.isEmpty(deleteListeners)) {
            for (InfoDeleteListener listener : deleteListeners) {
                listener.preInfoDelete(ids);
            }
        }
    }

    private String[] splitTagKeywords(String tagKeywords) {
        String split = Constants.TAG_KEYWORDS_SPLIT;
        if (StringUtils.isNotBlank(split)) {
            for (int i = 0, len = split.length(); i < len; i++) {
                tagKeywords = StringUtils.replace(tagKeywords, String.valueOf(split.charAt(i)), ",");
            }
        }
        return StringUtils.split(tagKeywords, ',');
    }

    private List<InfoListener> listeners;
    private List<InfoDeleteListener> deleteListeners;

    @Autowired(required = false)
    public void setListeners(List<InfoListener> listeners) {
        this.listeners = listeners;
    }

    @Autowired(required = false)
    public void setDeleteListeners(List<InfoDeleteListener> deleteListeners) {
        this.deleteListeners = deleteListeners;
    }

    // private PolicyFactory policyFactory;
    private HtmlService htmlService;
    private AttachmentRefService attachmentRefService;
    private CommentService commentService;
    private InfoOrgService infoOrgService;
    private InfoMemberGroupService infoMemberGroupService;
    private WorkflowService workflowService;
    private InfoAttributeService infoAttrService;
    private AttributeService attributeService;
    private InfoTagService infoTagService;
    private InfoSpecialService infoSpecialService;
    private InfoNodeService infoNodeService;
    private InfoDetailService infoDetailService;
    private InfoBufferService infoBufferService;
    private NodeService nodeService;
    private UserService userService;
    private SiteService siteService;
    protected PathResolver pathResolver;
    private NodeQueryService nodeQueryService;
    private InfoVoteService infoVoteService;
    private ModelService modelService;
    private OrgService orgService;

    // @Autowired
    // public void setPolicyFactory(PolicyFactory policyFactory) {
    // this.policyFactory = policyFactory;
    // }

    @Autowired
    public void setModelService(ModelService modelService) {
        this.modelService = modelService;
    }

    @Autowired
    public void setInfoVoteService(InfoVoteService infoVoteService) {
        this.infoVoteService = infoVoteService;
    }

    @Autowired
    public void setNodeQueryService(NodeQueryService nodeQueryService) {
        this.nodeQueryService = nodeQueryService;
    }
    @Autowired
    public void setHtmlService(HtmlService htmlService) {
        this.htmlService = htmlService;
    }

    @Autowired
    public void setAttachmentRefService(AttachmentRefService attachmentRefService) {
        this.attachmentRefService = attachmentRefService;
    }

    @Autowired
    public void setCommentService(CommentService commentService) {
        this.commentService = commentService;
    }

    @Autowired
    public void setInfoOrgService(InfoOrgService infoOrgService) {
        this.infoOrgService = infoOrgService;
    }

    @Autowired
    public void setInfoMemberGroupService(InfoMemberGroupService infoMemberGroupService) {
        this.infoMemberGroupService = infoMemberGroupService;
    }

    @Autowired
    public void setWorkflowService(WorkflowService workflowService) {
        this.workflowService = workflowService;
    }

    @Autowired
    public void setInfoAttrService(InfoAttributeService infoAttrService) {
        this.infoAttrService = infoAttrService;
    }

    @Autowired
    public void setAttributeService(AttributeService attributeService) {
        this.attributeService = attributeService;
    }

    @Autowired
    public void setInfoTagService(InfoTagService infoTagService) {
        this.infoTagService = infoTagService;
    }

    @Autowired
    public void setInfoSpecialService(InfoSpecialService infoSpecialService) {
        this.infoSpecialService = infoSpecialService;
    }

    @Autowired
    public void setInfoNodeService(InfoNodeService infoNodeService) {
        this.infoNodeService = infoNodeService;
    }

    @Autowired
    public void setInfoDetailService(InfoDetailService infoDetailService) {
        this.infoDetailService = infoDetailService;
    }

    @Autowired
    public void setInfoBufferService(InfoBufferService infoBufferService) {
        this.infoBufferService = infoBufferService;
    }

    @Autowired
    public void setNodeService(NodeService nodeService) {
        this.nodeService = nodeService;
    }

    @Autowired
    public void setUserService(UserService userService) {
        this.userService = userService;
    }

    @Autowired
    public void setSiteService(SiteService siteService) {
        this.siteService = siteService;
    }

    @Autowired
    public void setPathResolver(PathResolver pathResolver) {
        this.pathResolver = pathResolver;
    }

    private UploadHandler uploadHandler;
    private InfoQueryService query;
    private InfoDao dao;

    @Autowired
    public void setUploadHandler(UploadHandler uploadHandler) {
        this.uploadHandler = uploadHandler;
    }

    @Autowired
    public void setQuery(InfoQueryService query) {
        this.query = query;
    }

    @Autowired
    public void setDao(InfoDao dao) {
        this.dao = dao;
    }

    private HtmlGenerator htmlGenerator;
    @Autowired
    public  void setHtmlGenerator(HtmlGenerator htmlGenerator){this.htmlGenerator=htmlGenerator;}

    @Autowired
    public void setOrgService(OrgService orgService) {
        this.orgService = orgService;
    }

    @Override
    public Info getInfoById(Integer id) {
        return dao.findOne(id);
    }
}
